﻿using System;
using System.Drawing;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Runtime.Remoting.Messaging;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Event.ReactiveProgramming
{
    public partial class ReactiveForm : Form
    {
        public ReactiveForm()
        {
            InitializeComponent();

            BindFirstGroupButtons();
            BindSecondGroupButtons();
            BindThirdGroupButtons();
        }

        //********************start-事件模型和反应式模型***********************
        private void BindFirstGroupButtons()
        {
            btnFirstEventMode.Click += btnFirstEventMode_Click;

            //var clickedStream = Observable.FromEventPattern<EventArgs>(btnFirstReactiveMode,"Click");
            //clickedStream.Subscribe(e => MessageBox.Show("Hello world"));

            btnFirstReactiveMode.FromClickEventPattern()
                .Subscribe(e => MessageBox.Show("hello world"));

        }

        void btnFirstEventMode_Click(object sender, EventArgs e)
        {
            MessageBox.Show("hello world");
        }
        //********************end-事件模型和反应式模型***********************


        //********************start-异步模型***********************
        private void BindSecondGroupButtons()
        {
            btnSecondEventMode.Click += btnSecondEventMode_Click;
            BtnSecondEventAsyncModel.Click += BtnSecondEventAsyncModel_Click;
            btnSecondAsyncAwaitMode.Click += BtnSecondAsyncAwaitModeClick;

            btnSecondReactiveMode.FromClickEventPattern()
                .Subscribe(e =>
                {
                    Observable.Start(() =>
                    {
                        btnSecondReactiveMode.BackColor = Color.Coral;
                        Thread.Sleep(2000);
                        return "reactive mode";
                    })
                        .SubscribeOn(ThreadPoolScheduler.Instance)
                        .ObserveOn(this)
                        .Subscribe(x =>
                        {
                            lblMessage.Text = x;
                        });
                });
        }

        //start-异步事件模型-界面不假死
        void BtnSecondEventAsyncModel_Click(object sender, EventArgs e)
        {
            BtnSecondEventAsyncModel.BackColor = Color.Coral;

            Task.Run(() =>
            {
                Thread.Sleep(2000);
                Action showMessage = () => lblMessage.Text = "async event mode";
                lblMessage.Invoke(showMessage);
            });
        }
        //end-异步事件模型-界面不假死

        //start-普通事件模型-界面假死
        void btnSecondEventMode_Click(object sender, EventArgs e)
        {
            btnSecondEventMode.BackColor = Color.Coral;
            Thread.Sleep(2000);
            lblMessage.Text = "event mode";
        }
        //end-普通事件模型-界面假死


        //start-Async/Await模式-界面没有假死
        async void BtnSecondAsyncAwaitModeClick(object sender, EventArgs e)
        {
            await LongTimeOperator();
        }

        async Task LongTimeOperator()
        {
            btnSecondAsyncAwaitMode.BackColor = Color.Coral;

            var result = await Task.Delay(2000).ContinueWith((t, o) => "async/await mode", null);
            lblMessage.Text = result;
        }
        //end--Async/Await模式-界面没有假死

        //********************end-异步模型***********************


        //********************start-事件流***************************************
        private void BindThirdGroupButtons()
        {
            var increasedEventStream = BtnIncreasement.FromClickEventPattern()
                .Select(_ => 1);
            var decreasedEventStream = btnDecrement.FromClickEventPattern()
                .Select(_ => -1);

            increasedEventStream.Merge(decreasedEventStream)
                .Scan(0, (result, s) => result + s)
                .Subscribe(x => lblResult.Text = x.ToString());
        }
        //********************end-事件流***************************************


    }
}
